package com.example.common.mlivedata;

import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.Observer;

import com.blankj.utilcode.util.LogUtils;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class LiveDataBus<T> extends MutableLiveData<T> {
    //重写订阅方法 ->保证lastVersion = -1;
    @Override
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        super.observe(owner, observer);
        try {
            hookLastVersion(observer);
        } catch (NoSuchFieldException | NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
    private void hookLastVersion(Observer<? super T> observer) throws NoSuchFieldException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取livedata类型
        Class<LiveData> liveDataClass = LiveData.class;

        //反射获取livedata class 下的observer属性
        Field fieldmObserver = liveDataClass.getDeclaredField("mObservers");

        //破环属性私有性
        fieldmObserver.setAccessible(true);
        Object mObservers = fieldmObserver.get(this);

        //获取observers 类型
        Class<?> mObserversClass = mObservers.getClass();

        //获取mObserversClass 里面的方法
        Method methodGet  = mObserversClass.getDeclaredMethod("get", Object.class);
        methodGet.setAccessible(true);
        //执行get方法获取返回值
        Object entity = methodGet.invoke(mObservers, observer);

        //获取返回值
        Object observerWrapper = ((Map.Entry)entity).getValue();

        Field mLastVersion = observerWrapper.getClass().getSuperclass().getDeclaredField("mLastVersion");
        mLastVersion.setAccessible(true);

        Field mVersion = liveDataClass.getDeclaredField("mVersion");
        mVersion.setAccessible(true);

        Object mVersionObject = mVersion.get(this);
        //改变lastvertion值
        mLastVersion.set(observerWrapper,mVersionObject);
    }
}
